03 / 03

How do you manage internal vs public API boundaries within a Go module?

The internal/ package enforces compile-time import restrictions within a module. Minimizing exported identifiers and using unexported types is Go's primary API boundary mechanism.

Internal package structure
API design principles
  1. 1

    Unexported identifiers are free to change without versioning concerns — keep implementation details unexported

  2. 2

    Exported identifiers form a contract — once published, changing them requires a major version bump

  3. 3

    Accept interfaces, return concrete types in public APIs for flexibility

  4. 4

    Use internal/ for shared code across services in the same module without exposing it publicly

  5. 5

    Document exported identifiers — godoc generates documentation from exported types and functions